Skip to content

fix: wire real balance API and remove placeholders (#31)#169

Open
steph-crown wants to merge 1 commit intoPi-Defi-world:mainfrom
steph-crown:main
Open

fix: wire real balance API and remove placeholders (#31)#169
steph-crown wants to merge 1 commit intoPi-Defi-world:mainfrom
steph-crown:main

Conversation

@steph-crown
Copy link
Copy Markdown

@steph-crown steph-crown commented Mar 29, 2026

Replace hardcoded BALANCE_PLACEHOLDER ("—") on home, mint, and send
pages with live data from GET /users/me/balance.

  • Add BalanceResponse type and getBalance() API function
  • Add useBalance hook (loading, error, refetch support)
  • Wire home, mint, and send pages to real balance
  • Fix undefined exceedsBalance runtime error on send page
  • Remove duplicate TabsContent and stray in send page
  • Remove undefined BURN_DESTINATION_LABELS reference in mint page
  • Clean up unused imports (Skeleton, PageContainer)

Closes #31

Summary by CodeRabbit

  • New Features

    • Real wallet balances now display throughout the app, replacing static placeholders.
    • Added validation in send form to prevent exceeding available balance.
    • Balance automatically refreshes after successful transfers.
  • Bug Fixes

    • Fixed .gitignore file formatting issues.
  • Chores

    • Updated .gitignore with additional local cache directory patterns.

Replace hardcoded BALANCE_PLACEHOLDER ("—") on home, mint, and send
pages with live data from GET /users/me/balance.

- Add BalanceResponse type and getBalance() API function
- Add useBalance hook (loading, error, refetch support)
- Wire home, mint, and send pages to real balance
- Fix undefined exceedsBalance runtime error on send page
- Remove duplicate TabsContent and stray </div> in send page
- Remove undefined BURN_DESTINATION_LABELS reference in mint page
- Clean up unused imports (Skeleton, PageContainer)

Made-with: Cursor
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 29, 2026

📝 Walkthrough

Walkthrough

A new useBalance React hook has been introduced to fetch authenticated user wallet balances from the API. This hook is integrated into the mint, home, and send pages to replace static balance placeholders with dynamic, real-time balance data including loading and error states. Additionally, the send page validates that transfer amounts don't exceed available balance, and refetches balance after successful transfers.

Changes

Cohort / File(s) Summary
Balance Hook Infrastructure
hooks/use-balance.ts, types/api.ts, lib/api/user.ts
New useBalance() hook that fetches wallet balance via GET /users/me/balance with loading, error, and refetch states. Added BalanceResponse type and getBalance() API function.
Balance Display Updates
app/(app)/mint/page.tsx, app/(app)/page.tsx, app/(app)/send/page.tsx
Replaced hardcoded balance placeholders with dynamic balance values from useBalance() hook. Added loading indicators, error banners, and in send page added balance validation to prevent exceeding available balance and refetch after transfers.
Repository Configuration
.gitignore
Added .pnpm-store/ and .history/* to tracked exclusions; corrected next-env.d.ts file ending with trailing newline.

Sequence Diagram

sequenceDiagram
    participant Page as React Page
    participant Hook as useBalance Hook
    participant API as userApi
    participant Backend as Backend API

    Page->>Hook: Call useBalance()
    Hook->>Hook: Initialize state (balance, loading, error)
    activate Hook
    Hook->>API: Call getBalance()
    activate API
    API->>Backend: GET /users/me/balance
    activate Backend
    Backend-->>API: Return balance data
    deactivate Backend
    API-->>Hook: BalanceResponse
    deactivate API
    Hook->>Hook: Parse balance, set loading=false
    Hook-->>Page: Return {balance, loading, error, refetch}
    deactivate Hook
    Page->>Page: Render with dynamic balance or loading state
    
    Note over Page,Hook: User triggers refetch (e.g., after transfer)
    Page->>Hook: Call refetch()
    Hook->>Hook: Increment tick, restart fetch cycle
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 A hook hops in with balance so sweet,
No more placeholders to greet,
Real numbers dance as they load,
While errors fade down the road,
Refetch, and the wallet's complete! 💰

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: replacing hardcoded balance placeholders with real API data.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@drips-wave
Copy link
Copy Markdown

drips-wave bot commented Mar 29, 2026

@steph-crown Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
.gitignore (1)

29-30: Consider using leading / for root-level directories.

The new ignore patterns are appropriate, but for consistency with other root-level patterns in this file (e.g., /node_modules, /.next/), consider:

-.pnpm-store/
-.history/*
+/.pnpm-store/
+/.history/

This makes it explicit that these directories are expected at the repository root and follows the existing convention. The current form works correctly but is less precise.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.gitignore around lines 29 - 30, Update the root-level ignore patterns in
.gitignore to use a leading slash for consistency: replace occurrences of
".pnpm-store/" and ".history/*" with "/.pnpm-store/" and "/.history/*" so they
explicitly target repository-root directories; locate these patterns in the
.gitignore file and change the two entries (".pnpm-store/" and ".history/*")
accordingly.
hooks/use-balance.ts (1)

52-52: Dependency array includes opts.token but not the full opts object.

Per hooks/use-api.ts, useApiOpts() currently returns a stable empty object (useMemo(() => ({}), [])), so opts.token is always undefined and this works fine. If useApiOpts ever returns additional request options (e.g., signal, custom headers), those changes wouldn't trigger a refetch. Consider depending on opts directly if future-proofing is desired, though current behavior is correct.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hooks/use-balance.ts` at line 52, The hook's effect currently depends on
opts.token and tick, but because useApiOpts() may later return other request
options changes (like signal or headers) those won't trigger the refetch; update
the dependency array to depend on the full opts object (replace opts.token with
opts) so any change to the options returned by useApiOpts() causes the effect to
rerun—look for the effect inside the useBalance hook in hooks/use-balance.ts and
update its dependency array from [opts.token, tick] to [opts, tick].
app/(app)/mint/page.tsx (1)

36-36: Consider refetching balance after successful mint/burn operations.

Unlike send/page.tsx which calls refetchBalance() after a successful transfer (line 120), this page doesn't refresh the balance after mint or burn operations. The displayed balance will be stale until the user navigates away and back.

♻️ Proposed fix
- const { balance, loading: balanceLoading } = useBalance();
+ const { balance, loading: balanceLoading, refetch: refetchBalance } = useBalance();

Then call refetchBalance() after successful operations:

         setTxId(res.transaction_id);
         setStep("success");
+        refetchBalance();
       } catch (e) {

Apply similarly in handleExecuteBurn.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/`(app)/mint/page.tsx at line 36, The balance returned by useBalance is
not refreshed after mint/burn; destructure refetchBalance from useBalance (e.g.,
const { balance, loading: balanceLoading, refetchBalance } = useBalance()) and
invoke refetchBalance() after each successful operation in the handlers (call it
at the point where handleExecuteMint and handleExecuteBurn currently treat the
operation as successful, right after the success path/await completes) so the UI
shows the updated balance immediately.
app/(app)/send/page.tsx (1)

119-120: Balance refetch may return stale data immediately after transfer.

Per types/api.ts (lines 88-91), createTransfer returns only a transaction_id and status (which may be "pending"). The backend balance may not be updated yet when refetchBalance() is called. This is acceptable for now—the balance will eventually sync—but consider adding a brief delay or showing optimistic UI if precise balance is critical.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/`(app)/send/page.tsx around lines 119 - 120, The current flow calls
loadTransfers() and immediately refetchBalance(), but createTransfer (per
types/api.ts) can return a "pending" transaction_id so the backend balance may
not reflect the transfer yet; update the UI to avoid showing stale balance by
either adding a short delay before calling refetchBalance() (e.g., schedule
refetchBalance() with a small timeout after loadTransfers()) or implement an
optimistic UI: immediately update the cached/local balance and transfers list in
the client (subtract the sent amount and push a pending transfer entry) and then
call refetchBalance() to reconcile once the backend confirms; touch the code
around loadTransfers(), refetchBalance(), and the createTransfer handling to
implement one of these approaches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.gitignore:
- Around line 29-30: Update the root-level ignore patterns in .gitignore to use
a leading slash for consistency: replace occurrences of ".pnpm-store/" and
".history/*" with "/.pnpm-store/" and "/.history/*" so they explicitly target
repository-root directories; locate these patterns in the .gitignore file and
change the two entries (".pnpm-store/" and ".history/*") accordingly.

In `@app/`(app)/mint/page.tsx:
- Line 36: The balance returned by useBalance is not refreshed after mint/burn;
destructure refetchBalance from useBalance (e.g., const { balance, loading:
balanceLoading, refetchBalance } = useBalance()) and invoke refetchBalance()
after each successful operation in the handlers (call it at the point where
handleExecuteMint and handleExecuteBurn currently treat the operation as
successful, right after the success path/await completes) so the UI shows the
updated balance immediately.

In `@app/`(app)/send/page.tsx:
- Around line 119-120: The current flow calls loadTransfers() and immediately
refetchBalance(), but createTransfer (per types/api.ts) can return a "pending"
transaction_id so the backend balance may not reflect the transfer yet; update
the UI to avoid showing stale balance by either adding a short delay before
calling refetchBalance() (e.g., schedule refetchBalance() with a small timeout
after loadTransfers()) or implement an optimistic UI: immediately update the
cached/local balance and transfers list in the client (subtract the sent amount
and push a pending transfer entry) and then call refetchBalance() to reconcile
once the backend confirms; touch the code around loadTransfers(),
refetchBalance(), and the createTransfer handling to implement one of these
approaches.

In `@hooks/use-balance.ts`:
- Line 52: The hook's effect currently depends on opts.token and tick, but
because useApiOpts() may later return other request options changes (like signal
or headers) those won't trigger the refetch; update the dependency array to
depend on the full opts object (replace opts.token with opts) so any change to
the options returned by useApiOpts() causes the effect to rerun—look for the
effect inside the useBalance hook in hooks/use-balance.ts and update its
dependency array from [opts.token, tick] to [opts, tick].

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ff0c4694-d213-4435-945d-7cfe0db55a0c

📥 Commits

Reviewing files that changed from the base of the PR and between cbf1f90 and 2009982.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • .gitignore
  • app/(app)/mint/page.tsx
  • app/(app)/page.tsx
  • app/(app)/send/page.tsx
  • hooks/use-balance.ts
  • lib/api/user.ts
  • types/api.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Balance always placeholder

1 participant